﻿using DevelopTool.Model;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DevelopTool.Common
{
    public class DataGridViewHelper
    {
        /// <summary>
        /// 绑定数据
        /// </summary>
        /// <param name="dataTable"></param>
        /// <param name="rowFilter"></param>
        /// <param name="sortStr"></param>
        /// <returns></returns>
        public static BindingSource BindingSource(DataTable dataTable, string rowFilter = "", string sortStr = "")
        {
            BindingSource bindingSource = new BindingSource();

            if (dataTable == null) return bindingSource; //|| dataTable.Rows.Count <= 0

            dataTable = ConvertColumnDataType(dataTable);

            DataView dataview = dataTable.DefaultView;

            if (!string.IsNullOrEmpty(sortStr))
                dataview.Sort = sortStr;

            //if (!string.IsNullOrEmpty(rowFilter))
            //    dataview.RowFilter = rowFilter;

            dataview.RowFilter = rowFilter;

            bindingSource.DataSource = dataview;

            return bindingSource;
        }


        /// <summary>
        /// 转换DataTable的string[]或byte[]
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        private static DataTable ConvertColumnDataType(DataTable table)
        {
            // 首先获取所有列名，因为在迭代过程中可能会修改列集合
            var columnNames = new List<string>();
            foreach (DataColumn column in table.Columns)
            {
                columnNames.Add(column.ColumnName);
            }

            // 遍历每一列
            foreach (var columnName in columnNames)
            {
                // 获取当前列
                DataColumn column = table.Columns[columnName];

                // 检查列类型是否为string[]或byte[]
                if (column.DataType == typeof(string[]) || column.DataType == typeof(byte[]))
                {
                    // 创建一个新的列，用于存储转换后的字符串
                    string newColumnName = columnName + "_converted";
                    table.Columns.Add(newColumnName, typeof(string));

                    // 遍历每一行，将string[]或byte[]类型的数据转换为字符串
                    foreach (DataRow row in table.Rows)
                    {
                        if (column.DataType == typeof(string[]) && row[columnName] is string[] stringArray)
                        {
                            // 将string[]转换为用换行符分割的字符串
                            row[newColumnName] = string.Join("\n", stringArray);
                        }
                        else if (column.DataType == typeof(byte[]) && row[columnName] is byte[] byteArray)
                        {
                            // 将byte[]转换为UTF-8编码的字符串
                            row[newColumnName] = Encoding.UTF8.GetString(byteArray);
                        }
                        // 如果当前单元格不是string[]或byte[]类型，则跳过
                    }

                    // 删除原始列
                    table.Columns.Remove(columnName);

                    // 将新列重命名为原始列名
                    table.Columns[newColumnName].ColumnName = columnName;
                }
            }

            return table;
        }


        /// <summary>
        /// 设置DataTable的某些属性，后面有需要可以在这设置
        /// </summary>
        /// <param name="dataTable"></param>
        private static DataTable SetDataTableProperty(DataTable dataTable)
        {
            for (int i = 0; i < dataTable.Columns.Count; i++)
            {
                dataTable.Columns[i].ReadOnly = false;//设置DataTable的所有列不是只读，防止修改某一单元格的值时报错
            }
            return dataTable;
        }




        /// <summary>
        /// 设置DataGridView列信息
        /// </summary>
        /// <param name="dgv"></param>
        /// <param name="columnInfos"></param>
        public static void SetDataGridViewColumnInfo(DataGridView dgv, List<DataGridColumn> dataGridColumns)
        {
            if (dataGridColumns == null || dataGridColumns.Count <= 0) return;

            //从List<DataGridColumn>中删除DataGridView没有的列
            // dataGridColumns.RemoveAll(jt => !dgv.Columns.Cast<DataGridViewColumn>().Any(it => it.DataPropertyName == jt.ColumnName));

            int index = dgv.Columns.Count - 1;
            for (int j = 0; j < dgv.Columns.Count; j++)
            {
                DataGridColumn dataGridColumn = dataGridColumns.FirstOrDefault(it =>
                it.ColumnName.ToUpper() == dgv.Columns[j].HeaderText.ToUpper()
                || it.ColumnText.ToUpper() == dgv.Columns[j].HeaderText.ToUpper());

                if (dataGridColumn != null)
                {
                    dgv.Columns[j].DisplayIndex = dataGridColumns.LastIndexOf(dataGridColumn);//根据List<DataGridColumn>的Add顺序显示列位置

                    if (!string.IsNullOrEmpty(dataGridColumn.ColumnText))
                        dgv.Columns[j].HeaderText = dataGridColumn.ColumnText;//列标题

                    if (!string.IsNullOrEmpty(dataGridColumn.ValueFormat))
                        dgv.Columns[j].DefaultCellStyle.Format = dataGridColumn.ValueFormat;//数据格式

                    dgv.Columns[j].Tag = dataGridColumn;
                    dgv.Columns[j].Visible = !dataGridColumn.ColumnType.HasFlag(ColumnType.Hide);
                }
                else
                {
                    if (dataGridColumns.Count > 0)//没有指定列名的话，就按默认的列顺序吧
                        dgv.Columns[j].DisplayIndex = index--;
                }
            }
        }

        /// <summary>
        /// 设置dataGridView列宽度，尽量占满控件
        /// </summary>
        /// <param name="dgv"></param>
        /// <param name="dataGridColumns"></param>
        public static void SetDataGridViewColumnWidth(DataGridView dgv, List<DataGridColumn> dataGridColumns)
        {
            //根据列名长度，设置所有列的最小宽度，保证列名能完整显示
            for (int j = 0; j < dgv.Columns.Count; j++)
            {
                int minWidth = Convert.ToInt32(StringHelper.GetStrLength(dgv.Columns[j].HeaderText) * 9.9);
                dgv.Columns[j].MinimumWidth = minWidth < 2 ? 2 : minWidth;
                dgv.Columns[j].Width = 0;
            }

            if (dataGridColumns != null)
            {
                int remainingWidth = 0;//已经设置的列宽度总和

                var autoWidthColumns = dataGridColumns.FindAll(it => it.Width == -1 && !it.ColumnType.HasFlag(ColumnType.Hide));//获取自动设置宽度的列
                foreach (DataGridColumn autoWidthColumn in autoWidthColumns)
                {
                    for (int j = 0; j < dgv.Columns.Count; j++)
                    {
                        if (dgv.Columns[j].HeaderText == autoWidthColumn.ColumnText)
                        {
                            remainingWidth += dgv.Columns[j].MinimumWidth;
                            break;
                        }
                    }
                }

                var specifyWidthColumns = dataGridColumns.FindAll(it => it.Width > 0 && !it.ColumnType.HasFlag(ColumnType.Hide));//获取已设置宽度的列
                foreach (DataGridColumn specifyWidthColumn in specifyWidthColumns)
                {
                    for (int j = 0; j < dgv.Columns.Count; j++)
                    {
                        if (dgv.Columns[j].HeaderText == specifyWidthColumn.ColumnText)
                        {
                            dgv.Columns[j].Width = specifyWidthColumn.Width;
                            remainingWidth += specifyWidthColumn.Width;
                            break;
                        }
                    }
                }

                var fullWidthColumns = dataGridColumns.FindAll(it => it.Width == 0 && !it.ColumnType.HasFlag(ColumnType.Hide));//获取需要占满剩余宽度的列                                                                                     
                if (fullWidthColumns.Count > 0)
                {
                    int remainderWidth = dgv.Width - remainingWidth - dgv.RowHeadersWidth - 20;//剩余可分配宽度
                    int averageWidth = Convert.ToInt32(remainderWidth / fullWidthColumns.Count);//计算可平均分配的宽度

                    foreach (DataGridColumn fullWidthColumn in fullWidthColumns)
                    {
                        for (int j = 0; j < dgv.Columns.Count; j++)
                        {
                            if (dgv.Columns[j].HeaderText == fullWidthColumn.ColumnText)
                            {
                                dgv.Columns[j].Width = averageWidth;
                                break;
                            }
                        }
                    }
                }

            }
        }


        /// <summary>
        /// DataGridView添加序号列
        /// </summary>
        /// <param name="DataGridView"></param>
        /// <param name="e"></param>
        public static void AddColumnHeader(DataGridView dgv, DataGridViewRowPostPaintEventArgs e)
        {
            #region 绘制序号列
            // 获取当前行的行号
            string rowNumber = (e.RowIndex + 1).ToString();
            // 将行号绘制到行标题单元格中
            SizeF size = e.Graphics.MeasureString(rowNumber, dgv.Font);
            if (dgv.RowHeadersWidth < (int)(size.Width + 20))
            {
                dgv.RowHeadersWidth = (int)(size.Width + 20);
            }

            //按主题绘制
            Brush brush = SystemBrushes.ControlText;
            switch (Setting.Theme.ControlThemColor)
            {
                case UIMenuStyle.Black:
                    brush = new SolidBrush(Color.White);
                    break;
                case UIMenuStyle.White:
                    break;
            }

            e.Graphics.DrawString(rowNumber, dgv.RowsDefaultCellStyle.Font, brush, e.RowBounds.Location.X + 10, e.RowBounds.Location.Y + ((e.RowBounds.Height - size.Height) / 2));
            #endregion
        }


        /// <summary>
        /// 复制当前选择的单元格的标题文本（支持多选）
        /// </summary>
        /// <param name="dgv"></param>
        public static void CopyDataGridViewTitleText(DataGridView dgv)
        {
            List<string> texts = new List<string>();
            foreach (DataGridViewCell cell in dgv.SelectedCells)
            {
                var headerText = cell.OwningColumn.HeaderText;//获得当前单元格的标题文本
                if (!texts.Any(it => it.Equals(headerText)))
                {
                    texts.Add(headerText);
                }
            }
            texts.Reverse();//这里需要反转一下，我也不知道为啥~
            Clipboard.SetText(string.Join(" ", texts.ToArray()));//复制多个标题列，以空格分割
        }
    }
}
